﻿#include "ChooseFriendDialog.h"
#include <QCheckBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QScrollArea>
#include <QStyleOption>
#include "Custom/CircleButton.h"
#include "Debug.h"
#include "Style.h"
#include "Model/DataCenter.h"
#include "Toast.h"

using namespace model;

////////////////////////////////////////////
/// 点击三个点后, 继续点击添加按钮弹出的画面
////////////////////////////////////////////
/// @brief 构造整体的界面
/// @param friend_user_info 好友的信息
/// @param parent 
ChooseFriendDialog::ChooseFriendDialog(UserInfo* friend_user_info, QWidget* parent)
    : friend_user_info(friend_user_info), QDialog(parent)
{
    /* 1. 基本属性初始化 */
    this->setWindowTitle("选择好友");
    this->setWindowIcon(QIcon(":/image/logo.png"));
    this->setAttribute(Qt::WA_DeleteOnClose);
    this->setFixedSize(600, 600);
    this->left_widget  = new QWidget();
    this->right_widget = new QWidget();
    /* 2. 创建水平布局 */
    out_h_layout = new QHBoxLayout();
    out_h_layout->setContentsMargins(0, 0, 0, 0);
    out_h_layout->setSpacing(0);
    this->setLayout(out_h_layout);
    data_center = DataCenter::get_instance();
    /* 3. 初始化左边和右边 */
    init_left();
    init_right();
    /* 4. 添加数据 */
    add_data_fake();
    add_data_network();
}

/// @brief 初始化左边的好友列表
void ChooseFriendDialog::init_left()
{
    /* 1. 创建QSCrollArea */
    QScrollArea* s_area = new QScrollArea();
    out_h_layout->addWidget(s_area, 1); // 各占1份
    s_area->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    s_area->setWidgetResizable(true);
    s_area->setStyleSheet(SCROLL_STYLE);
    s_area->setWidget(left_widget);
    /* 2. 创建垂直布局 */
    QVBoxLayout* v_layout = new QVBoxLayout();
    v_layout->setContentsMargins(0, 0, 0, 0);
    v_layout->setSpacing(0);
    left_widget->setLayout(v_layout);
}

/// @brief 初始化右边的选中的好友列表
void ChooseFriendDialog::init_right()
{
    /* 1. 创建QSCrollArea */
    QScrollArea* s_area = new QScrollArea();
    out_h_layout->addWidget(s_area, 1); // 各占1份
    s_area->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    s_area->setWidgetResizable(true);
    s_area->setStyleSheet(SCROLL_STYLE);
    s_area->setWidget(right_widget);
    /* 2. 创建垂直布局 */
    QVBoxLayout* v_layout = new QVBoxLayout();
    v_layout->setContentsMargins(0, 0, 0, 0);
    v_layout->setSpacing(0);
    right_widget->setLayout(v_layout);
    /* 3. 添加测试数据, 实际应由左侧点击而来 */
#ifdef __TEST_UI_DISABLED__
    for (int i = 1; i <= 30; ++i) {
        add_item(v_layout, "1000" + QString::number(i), false, QIcon(":/image/vanilla2.png"),
                 "香草" + QString::number(i));
    }
#endif
    /* 4. 添加保存和取消按钮 */
    QWidget* btn_container = new QWidget();
    btn_container->setStyleSheet(
        "QPushButton {"
        "font-size: 14px;"
        "border-radius: 5px;"
        "}");
    QHBoxLayout* h_layout = new QHBoxLayout();
    btn_container->setLayout(h_layout);
    h_layout->setContentsMargins(20, 0, 20, 0);
    h_layout->setSpacing(20);
    const QSize  b_size = QSize(80, 30);
    save   = new QPushButton();
    save->setFixedSize(b_size);
    save->setText("保存");
    save->setStyleSheet(
        "QPushButton{"
        "background-color: #0099FF;"
        "}"
        "QPushButton:hover {"
        "background-color: #0093F5;"
        "}"
        "QPushButton:pressed {"
        "background-color: #0086E0;"
        "}");
    cancel = new QPushButton();
    cancel->setFixedSize(b_size);
    cancel->setText("取消");
    cancel->setStyleSheet(
        "QPushButton{"
        "background-color: #F2F2F2;"
        "border: 1px solid #757575;"
        "}"
        "QPushButton:hover {"
        "background-color: #E9E9E9;"
        "}"
        "QPushButton:pressed {"
        "background-color: #D5D5D5;"
        "}");
    h_layout->addWidget(save);
    h_layout->addWidget(cancel);
    v_layout->addWidget(btn_container, 0, Qt::AlignTop);
    /* 5. 处理点击保存和取消的信号槽 */
    connect(cancel, &QPushButton::clicked, this, [this]() {
        this->close();
    });
    connect(save, &QPushButton::clicked, this, &ChooseFriendDialog::handle_click_ok_btn);
}

/// @brief 测试, 向左侧的 layout添加 item
void ChooseFriendDialog::add_data_fake()
{
#ifdef TEST_UI
    /* 获取左面元素的布局 */
    QVBoxLayout* left_v_layout = dynamic_cast<QVBoxLayout*>(left_widget->layout());
    if (left_v_layout == nullptr) {
        LOG() << "dynamic error";
    }
    /* 获取右面元素的布局 */
    QVBoxLayout* right_v_layout = dynamic_cast<QVBoxLayout*>(right_widget->layout());
    if (right_v_layout == nullptr) {
        LOG() << "dynamic error";
    }
    for (int i = 1; i <= 30; ++i) {
        /* 往左边添加元素 */
        ChooseFriendDialogItem::add_item(left_v_layout, right_v_layout, true, "1000" + QString::number(i), false, QIcon(":/image/chocolate.png"),
                                         "巧克力" + QString::number(i));
    }
#endif
}

/// @brief 从网络获取数据, 添加到左边和右边
void ChooseFriendDialog::add_data_network()
{
    QVBoxLayout* left_v_layout = dynamic_cast<QVBoxLayout*>(left_widget->layout());
    if (left_v_layout == nullptr) {
        LOG() << "dynamic error";
        return;
    }

    QVBoxLayout* right_v_layout = dynamic_cast<QVBoxLayout*>(right_widget->layout());
    if (right_v_layout == nullptr) {
        LOG() << "dynamic error";
        return;
    }

    QList<UserInfo>* user_list = data_center->get_friend_list();
    const UserInfo*  my_info   = data_center->get_cur_user_info();

     // 添加自己到左侧和右侧
    ChooseFriendDialogItem::add_item(left_v_layout, right_v_layout, true,
                                     my_info->user_id, true, my_info->avatar, my_info->nick_name);

    ChooseFriendDialogItem::add_item(left_v_layout, right_v_layout, false,
                                     my_info->user_id, true, my_info->avatar, my_info->nick_name);

    // 添加好友列表到左侧
    for (const auto& user : *user_list) {
        bool is_selected = (user.user_id == friend_user_info->user_id);
        ChooseFriendDialogItem::add_item(left_v_layout, right_v_layout, true,
                                         user.user_id, is_selected, user.avatar, user.nick_name);

        // 如果是传入的好友，添加到右侧
        if (is_selected) {
            ChooseFriendDialogItem::add_item(left_v_layout, right_v_layout, false,
                                             user.user_id, true, user.avatar, user.nick_name);
        }
    }
}

/// @brief 点击确定按钮, 获得成员列表, 然后发送创建群组的请求
void ChooseFriendDialog::handle_click_ok_btn()
{
    QList<QString> user_id_list = generate_member_list();
    if (user_id_list.size() < 2) {
        LOG() << "member list size < 2";
        Toast::showMessage("成员数应大于2!");
        return;
    }
    data_center->create_group_async(user_id_list);
    this->close();
}

/// @brief 根据当前选中的列表生成成员列表
QList<QString> ChooseFriendDialog::generate_member_list()
{
    QList<QString> member_list;
    QVBoxLayout* right_v_layout = dynamic_cast<QVBoxLayout*>(right_widget->layout());
    if (right_v_layout == nullptr) {
        LOG() << "dynamic error";
        return member_list;
    }
    for (int i = 0; i < right_v_layout->count(); ++i) {
        QLayoutItem* item = right_v_layout->itemAt(i);
        ChooseFriendDialogItem* item_widget = dynamic_cast<ChooseFriendDialogItem*>(item->widget());
        if (item_widget == nullptr) {
            // LOG() << "dynamic error";
            continue;
        }
        member_list.append(item_widget->get_id());
    }
    return member_list;
}

////////////////////////////////////////////
/// ChooseFriendDialog使用的一条一条的item
/// 包含是是否选中, 头像, 昵称这几个属性
////////////////////////////////////////////
ChooseFriendDialogItem::ChooseFriendDialogItem()
{
}

ChooseFriendDialogItem::ChooseFriendDialogItem(
    QVBoxLayout* left_v_layout, QVBoxLayout* right_v_layout,
    const QString& id, bool is_checked, const QIcon& avatar, const QString& name)
    : id(id), is_checked(is_checked), avatar(avatar), name(name)
{
    /* 1. init */
    // LOG() << "In construct";
    const static int HEIGHT = 50;
    this->setFixedHeight(HEIGHT); // 一条长HEIGHT
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    const QSize icon_size = QSize(HEIGHT - 10, HEIGHT - 10);
    /* 2. 创建复选框 */
    ck_box = new QCheckBox();
    ck_box->setChecked(is_checked);
    ck_box->setStyleSheet(
        "QCheckBox {"
        "background-color: transparent;"
        "}"
        "QCheckBox::indicator {"
        "width: 25px;"
        "height: 25px;"
        "image: url(:/image/unchecked.png);"
        "}"
        "QCheckBox::indicator:checked {"
        "width: 25px;"
        "height: 25px;"
        "image: url(:/image/checked.png);"
        "}");
    /* 3. 头像 */
    CircleButton* btn = new CircleButton();
    btn->setFixedSize(icon_size);
    btn->setIconSize(icon_size);
    btn->setIcon(avatar);
    btn->setStyleSheet(
        "QPushButton {"
        "background-color: transparent;"
        "}");
    /* 4. 昵称 */
    QLabel* name_label = new QLabel();
    name_label->setFixedHeight(HEIGHT);
    name_label->setStyleSheet(
        "QLabel {"
        "font-size: 14px"
        "background-color: tansparent;"
        "}");
    name_label->setText(name);
    // LOG() << "before add layout";
    /* 5. 添加布局 */
    QHBoxLayout* h_layout = new QHBoxLayout();
    h_layout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    h_layout->setContentsMargins(20, 0, 0, 0);
    h_layout->setSpacing(10);
    this->setLayout(h_layout);
    h_layout->addWidget(ck_box);
    h_layout->addWidget(btn);
    h_layout->addWidget(name_label);
    /* 6. 处理复选框的信号槽逻辑 */
    connect(this->ck_box, &QCheckBox::toggled, this, [=]() {
        /* 使用[=]捕获指针后, 指针的类型是指针常量, T* const */
        if (ck_box->isChecked()) {
            this->add_item(left_v_layout, right_v_layout, false, id, true, avatar, name);
        } else {
            this->del_item(left_v_layout, right_v_layout, id);
        }
    });
}

/// @brief 向左边或者右边的布局添加Item
/// @param left_v_layout: 左边的QVBoxLayout布局
/// @param right_v_layout: 右边的QVBoxLayout布局
/// @param is_left: true表示往左边添加, false表示往右边添加
void ChooseFriendDialogItem::add_item(
    QVBoxLayout* const left_v_layout, QVBoxLayout* const right_v_layout, bool is_left,
    const QString& id, bool is_checked, const QIcon& avatar, const QString& name)
{
    if (left_v_layout == nullptr || right_v_layout == nullptr) {
        LOG() << "Invalid layout pointers!";
        return;
    }
    ChooseFriendDialogItem* item = new ChooseFriendDialogItem(left_v_layout, right_v_layout, id, is_checked, avatar, name);
    // LOG() << "after create ChooseItem";
    if (is_left == true) {
        if (left_v_layout == nullptr) {
            LOG() << "error parm!";
            return;
        }
        left_v_layout->addWidget(item);
    } else {
        /* 右边的布局, 向前插入 */
        if (right_v_layout == nullptr) {
            LOG() << "error parm!";
            return;
        }
        int cnt = right_v_layout->count();
        if (cnt < 1) {
            LOG() << "invalid count!";
            return;
        }
        right_v_layout->insertWidget(cnt - 1, item);
    }
}

/// @brief 在右侧的right_v_layout垂直布局中删除等于传入id的元素
void ChooseFriendDialogItem::del_item(
    QVBoxLayout* const left_v_layout, QVBoxLayout* const right_v_layout, const QString& id)
{
    /* 1. 删除右侧的item */
    for (int i = right_v_layout->count() - 1; i >= 0; --i) {
        QLayoutItem* i_layout_item = right_v_layout->itemAt(i);
        if (i_layout_item == nullptr || i_layout_item->widget() == nullptr) {
            LOG() << "invalid QLayoutItem!";
            continue;
        }
        ChooseFriendDialogItem* item = dynamic_cast<ChooseFriendDialogItem*>(i_layout_item->widget());
        if (item == nullptr) {
            // LOG() << "dynamic cast error";
            continue;
        }
        if (item->id != id) {
            /* find next */
            continue;
        }
        /* find the same id */
        right_v_layout->removeItem(i_layout_item);
        delete i_layout_item;
        item->deleteLater(); // 下次事件循环再删除, 直接删除会报错, 因为还没完全结束信号槽操作, 该信号槽操作是在ChooseFriendDialogItem中定义的
    }
    /* 修改左侧的check_box状态 */
    for (int i = left_v_layout->count() - 1; i >= 0; --i) {
        QLayoutItem* i_layout_item = left_v_layout->itemAt(i);
        if (i_layout_item == nullptr || i_layout_item->widget() == nullptr) {
            LOG() << "invalid QLayoutItem!";
            continue;
        }
        ChooseFriendDialogItem* item = dynamic_cast<ChooseFriendDialogItem*>(i_layout_item->widget());
        if (item == nullptr) {
            // LOG() << "dynamic cast error";
            continue;
        }
        if (item->id != id) {
            /* find next */
            continue;
        }
        /* find the same id */
        item->ck_box->setChecked(false);
    }
}

/// @brief 获取用户ID
QString ChooseFriendDialogItem::get_id()
{
    return id;
}

void ChooseFriendDialogItem::mousePressEvent(QMouseEvent* event)
{
    Q_UNUSED(event);
    ck_box->click();
}

void ChooseFriendDialogItem::enterEvent(QEnterEvent* event)
{
    Q_UNUSED(event);
    this->setStyleSheet(
        "QWidget {"
        "background-color: #E7E7E7}");
}

void ChooseFriendDialogItem::leaveEvent(QEvent* event)
{
    Q_UNUSED(event);
    this->setStyleSheet(
        "QWidget {"
        "background-color: #FFFFFF}");
}

void ChooseFriendDialogItem::paintEvent(QPaintEvent* event)
{
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
